package com.starlink.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starlink.client.ras.RasClient;
import com.starlink.client.ras.request.GoodsAddRequest;
import com.starlink.client.ras.response.RasBaseResponse;
import com.starlink.common.PageInfoTwo;
import com.starlink.common.exception.BusinessException;
import com.starlink.common.utils.AssertUtil;
import com.starlink.context.SessionContext;
import com.starlink.model.domain.*;
import com.starlink.model.dtomapper.MallBooksDetailDtoMapper;
import com.starlink.mapper.MallBooksDetailMapper;
import com.starlink.model.request.*;
import com.starlink.model.request.save.MallBooksSaveRequest;
import com.starlink.model.request.save.MallBooksSpecificationSaveRequest;
import com.starlink.model.util.MallBooksDetailConvert;
import com.starlink.model.vo.*;
import com.starlink.model.vo.book.MallBooksDetailsVO;
import com.starlink.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static com.starlink.utils.IDUtils.getId;

/**
 * @author zhanghong
 */
@Service
public class MallBooksDetailServiceImpl extends ServiceImpl<MallBooksDetailMapper, MallBooksDetailDO> implements MallBooksDetailService {
    @Autowired
    private MallBooksDetailMapper mallBooksDetailMapper;
    @Autowired
    private MallBooksService mallBooksService;
    @Autowired
    private MallOrderDetailsService bookOrderDetailsService;
    @Autowired
    private MallBooksSpecificationService specificationService;
    @Autowired
    private MallBooksCategoryService booksCategoryService;
    @Autowired
    private UserProductCollectService productCollectService;
    @Autowired
    private FreeTemplateService freeTemplateService;
    @Autowired
    private ShoppingCartOrderDetailsService cartOrderDetailsService;
    @Autowired
    private RasClient rasClient;

    @Override
    public MallBooksDetailVO getByKey(long id) {
        MallBooksDetailVO mallBooksDetailVO = MallBooksDetailDtoMapper.INSTANCE.do2VO(getById(id));
        return mallBooksDetailVO;
    }

    @Override
    public PageInfoTwo<MallBooksDetailVO> pageQuery(MallBooksDetailRequest request) {
        long count = mallBooksDetailMapper.pageCount(request);
        List<MallBooksDetailDO> list = mallBooksDetailMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<MallBooksDetailVO> mallBooksDetailVOList = MallBooksDetailConvert.buildMallBooksDetailVoList(list);
        return new PageInfoTwo(request.getPageNum(), request.getPageSize(), mallBooksDetailVOList, count);
    }

    @Override
    public List<MallBooksDetailVO> listQuery(MallBooksDetailRequest request) {
        List<MallBooksDetailDO> list = mallBooksDetailMapper.selectDOList(MallBooksDetailDtoMapper.INSTANCE.request2DO(request));
        List<MallBooksDetailVO> mallBooksDetailVOS = MallBooksDetailConvert.buildMallBooksDetailVoList(list);
        return mallBooksDetailVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(MallBooksDetailRequest request) {
        request.setId(getId());
        mallBooksDetailMapper.insertDO(MallBooksDetailDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(MallBooksDetailRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        mallBooksDetailMapper.updateDO(MallBooksDetailDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(String ids) {
        mallBooksService.deleteDOById(ids);
        return true;
    }

    @Override
    public MallBooksDetailsVO selectByParam(MallBooksDetailRequest request) {
        MallBooksDetailsVO detailsVO = new MallBooksDetailsVO();
        Long mallBooksId = request.getMallBooksId();
        MallBooksVO mallBooksVO = mallBooksService.getByKey(mallBooksId);
        if (!ObjectUtils.isEmpty(mallBooksVO)) {
            detailsVO.setMallBooksId(mallBooksVO.getId());
            detailsVO.setTitle(mallBooksVO.getTitle());
            detailsVO.setAuthor(mallBooksVO.getAuthor());
            detailsVO.setPublishingHouse(mallBooksVO.getPublishingHouse());
            detailsVO.setPicture(mallBooksVO.getPicture());
            detailsVO.setOnTheShelf(mallBooksVO.getOnTheShelf());
            detailsVO.setSortOrder(mallBooksVO.getSortOrder());
        }
        MallBooksDetailDO mallBooksDetailDO = mallBooksDetailMapper.selectDOByMallBooksId(mallBooksId);
        if (!ObjectUtils.isEmpty(mallBooksDetailDO)) {
            detailsVO.setId(mallBooksDetailDO.getId());
            detailsVO.setInterest(mallBooksDetailDO.getInterest());
            detailsVO.setQuality(mallBooksDetailDO.getQuality());
            detailsVO.setGuide(mallBooksDetailDO.getGuide());
            detailsVO.setDescription(mallBooksDetailDO.getDescription());
            detailsVO.setIntroduction(mallBooksDetailDO.getIntroduction());
            detailsVO.setHarvest(mallBooksDetailDO.getHarvest());
            detailsVO.setRead(mallBooksDetailDO.getRead());
            detailsVO.setLook(mallBooksDetailDO.getLook());
            detailsVO.setReady(mallBooksDetailDO.getReady());
        }
        MallBooksSpecificationRequest specificationRequest = new MallBooksSpecificationRequest();
        specificationRequest.setMallBooksId(mallBooksId);
        List<MallBooksSpecificationVO> specificationVOS = specificationService.listQuery(specificationRequest);
        if (CollectionUtils.isNotEmpty(specificationVOS)) {
            detailsVO.setSpecificationRequests(specificationVOS);
        }
        detailsVO.setProductType(1);
        Long collectId = productCollectService.selectByBookId(mallBooksId,SessionContext.getWechatUserId());
        if (collectId!=null){
            detailsVO.setCollectId(collectId);
        }
        List<MallBooksVO> randomBooks = mallBooksService.selectRandomBooks(mallBooksId);
        if (CollectionUtils.isNotEmpty(randomBooks)){
            List<MallBooksVO> mallBooksVOS = randomBooks.stream().filter(item -> item.getId() != mallBooksId).collect(Collectors.toList());
            detailsVO.setRandomBooks(getRandomDistinctItems(mallBooksVOS, 3));
        }
        return detailsVO;
    }

    public static <T> List<T> getRandomDistinctItems(List<T> list, int count) {
        if (list.size() <= count) {
            return list; // Return the whole list if count is greater than or equal to list size
        }

        // Shuffle the list
        Collections.shuffle(list);

        // Return the first 'count' items
        return list.subList(0, count);
    }

    @Override
    public MallBooksDetailsVO getByMallbooksId(Long mallBooksId) {
        MallBooksDetailsVO detailsVO = new MallBooksDetailsVO();
        MallBooksVO mallBooksVO = mallBooksService.getByKey(mallBooksId);
        if (!ObjectUtils.isEmpty(mallBooksVO)) {
            Long freeTemplateId = mallBooksVO.getFreeTemplateId();
            FreeTemplateDO freeTemplateDO = freeTemplateService.lambdaQuery().eq(FreeTemplateDO::getId,freeTemplateId).one();
            if (freeTemplateDO==null){
                detailsVO.setFreeTemplateName("原本的运费模板已被删除,请重新选择!");
            }else {
                detailsVO.setFreeTemplateId(freeTemplateId);
                detailsVO.setFreeTemplateName(freeTemplateDO.getTempName());
            }
            detailsVO.setMallBooksId(mallBooksVO.getId());
            detailsVO.setTitle(mallBooksVO.getTitle());
            detailsVO.setAuthor(mallBooksVO.getAuthor());
            detailsVO.setPublishingHouse(mallBooksVO.getPublishingHouse());
            detailsVO.setPicture(mallBooksVO.getPicture());
            detailsVO.setOnTheShelf(mallBooksVO.getOnTheShelf());
            detailsVO.setSortOrder(mallBooksVO.getSortOrder());
            detailsVO.setIsbnNum(mallBooksVO.getIsbnNum());

        }
        MallBooksDetailDO mallBooksDetailDO = mallBooksDetailMapper.selectDOByMallBooksId(mallBooksId);
        if (!ObjectUtils.isEmpty(mallBooksDetailDO)) {
            detailsVO.setId(mallBooksDetailDO.getId());
            detailsVO.setInterest(mallBooksDetailDO.getInterest());
            detailsVO.setQuality(mallBooksDetailDO.getQuality());
            detailsVO.setGuide(mallBooksDetailDO.getGuide());
            detailsVO.setDescription(mallBooksDetailDO.getDescription());
            detailsVO.setIntroduction(mallBooksDetailDO.getIntroduction());
            detailsVO.setHarvest(mallBooksDetailDO.getHarvest());
            detailsVO.setRead(mallBooksDetailDO.getRead());
            detailsVO.setLook(mallBooksDetailDO.getLook());
            detailsVO.setReady(mallBooksDetailDO.getReady());
        }
        MallBooksSpecificationRequest specificationRequest = new MallBooksSpecificationRequest();
        specificationRequest.setMallBooksId(mallBooksId);
        List<MallBooksSpecificationVO> specificationVOS = specificationService.listQuery(specificationRequest);
        if (CollectionUtils.isNotEmpty(specificationVOS)) {
            detailsVO.setSpecificationRequests(specificationVOS);
        }
        List<MallBooksCategoryVO> mallBooksCategoryVOS = booksCategoryService.selectByBookId(mallBooksId);
        if (CollectionUtils.isNotEmpty(mallBooksCategoryVOS)) {
            List<Long> categoryIds = mallBooksCategoryVOS.stream().map(MallBooksCategoryVO::getMallCategoryId).collect(Collectors.toList());
            detailsVO.setCategoryIds(categoryIds);
        }
        return detailsVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editing(MallBooksDetailAddRequest request) {
        Long adminUserId = SessionContext.getAdminUserId();
        MallBooksSaveRequest mallBooksRequest = new MallBooksSaveRequest();
        mallBooksRequest.setId(request.getMallBooksId());
        mallBooksRequest.setFreeTemplateId(request.getFreeTemplateId());
        mallBooksRequest.setTitle(request.getTitle());
        mallBooksRequest.setAuthor(request.getAuthor());
        mallBooksRequest.setPublishingHouse(request.getPublishingHouse());
        mallBooksRequest.setPicture(request.getPicture());
        mallBooksRequest.setSortOrder(request.getSortOrder());
        mallBooksRequest.setIsbnNum(request.getIsbnNum());
        List<MallBooksSpecificationSaveRequest> specificationRequests = request.getSpecificationRequests();
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        //书籍基本信息
        if (mallBooksRequest.getId() == null) {
            atomicBoolean.set(true);
            mallBooksRequest.setOnTheShelf(0);
            List<MallBooksDO> list = mallBooksService.lambdaQuery().eq(MallBooksDO::getIsbnNum, request.getIsbnNum()).list();
            AssertUtil.assertFalse(CollectionUtils.isNotEmpty(list),"该类书籍已存在,不可重复添加!");
            mallBooksService.add(mallBooksRequest);
        } else {
            mallBooksService.updateDO(mallBooksRequest);
        }
        //书籍详情
        MallBooksDetailRequest detailRequest = new MallBooksDetailRequest();
        detailRequest.setId(request.getId());
        detailRequest.setMallBooksId(mallBooksRequest.getId());
        detailRequest.setInterest(request.getInterest());
        detailRequest.setQuality(request.getQuality());
        detailRequest.setGuide(request.getGuide());
        detailRequest.setDescription(request.getDescription());
        detailRequest.setIntroduction(request.getIntroduction());
        detailRequest.setHarvest(request.getHarvest());
        detailRequest.setReady(request.getReady());
        detailRequest.setRead(request.getRead());
        detailRequest.setLook(request.getLook());
        if (detailRequest.getId()==null){
            detailRequest.setCreateUser(adminUserId);
            this.add(detailRequest);
        }else {
            detailRequest.setUpdateUser(adminUserId);
            detailRequest.setUpdateTime(new Date());
            this.updateByKey(detailRequest);
        }

        if (CollectionUtils.isNotEmpty(specificationRequests)) {
            List<MallBooksSpecificationDO> specificationDOS = specificationService.lambdaQuery().eq(MallBooksSpecificationDO::getMallBooksId, mallBooksRequest.getId()).list();
            if (CollectionUtils.isNotEmpty(specificationDOS)){
                List<Long> list = new ArrayList<>();
                List<Long> speIdList = specificationRequests.stream().map(MallBooksSpecificationSaveRequest::getId).collect(Collectors.toList());
                List<Long> longs = specificationDOS.stream().map(MallBooksSpecificationDO::getId).collect(Collectors.toList());
                longs.forEach(id->{
                    if (!speIdList.contains(id)){
                       list.add(id);
                    }
                });
                if (CollectionUtils.isNotEmpty(list)){
                    List<MallBooksOrderDetailsDO> bookOrderList = bookOrderDetailsService.lambdaQuery().in(MallBooksOrderDetailsDO::getSpecificationId, list).list();
                    List<ShoppingCartOrderDetailsDO> cartOrderDetailsDOList = cartOrderDetailsService.lambdaQuery().in(ShoppingCartOrderDetailsDO::getSpecificationId, list).list();
                    if (CollectionUtils.isNotEmpty(bookOrderList) || CollectionUtils.isNotEmpty(cartOrderDetailsDOList)){
                        throw new BusinessException("您删除的规格存在订单关联,暂不能删除");
                    }
                }
            }
            specificationService.lambdaUpdate().eq(MallBooksSpecificationDO::getMallBooksId, mallBooksRequest.getId()).remove();
            //规格
            specificationRequests.forEach(specification -> {
                String specification1 = specification.getSpecification();
                BigDecimal price = specification.getPrice();
                BigDecimal vipPrice = specification.getVipPrice();
                BigDecimal volume = specification.getVolume();
                BigDecimal weight = specification.getWeight();
                AssertUtil.assertNotNull(specification1,"规格名称不能为空!");
                AssertUtil.assertNotNull(price,"价格不能为空!");
                AssertUtil.assertNotNull(vipPrice,"VIP价格不能为空!");
                AssertUtil.assertNotNull(volume,"体积不能为空!");
                AssertUtil.assertNotNull(weight,"重量不能为空!");
                specification.setMallBooksId(mallBooksRequest.getId());
                specificationService.add(specification);
            });
        }

        if (CollectionUtils.isNotEmpty(request.getCategoryIds())) {
            booksCategoryService.lambdaUpdate().eq(MallBooksCategoryDO::getMallBooksId, mallBooksRequest.getId()).remove();
            //分类
            request.getCategoryIds().forEach(categoryId -> {
                MallBooksCategoryRequest categoryRequest = new MallBooksCategoryRequest();
                categoryRequest.setMallBooksId(mallBooksRequest.getId());
                categoryRequest.setMallCategoryId(categoryId);
                booksCategoryService.add(categoryRequest);
            });
        }
        if (atomicBoolean.get()) {
            GoodsAddRequest goodsAddRequest = new GoodsAddRequest();
            goodsAddRequest.setProductName(request.getTitle());
            goodsAddRequest.setMainImageOfTheProduct(request.getPicture());
            RasBaseResponse<Integer> goodsAdd = rasClient.goodsAdd(goodsAddRequest);
            Integer addData = goodsAdd.getData();
            AssertUtil.assertNotNull(addData, "RAS添加商品失败!");
            Long goodsId = Long.valueOf(addData);
            AssertUtil.assertNotNull(goodsId, "RAS服务返回商品ID为空!");
            mallBooksService.lambdaUpdate().set(MallBooksDO::getRasGoodsId, goodsId).eq(MallBooksDO::getId,mallBooksRequest.getId()).update();
        }
        return true;
    }
}